import { ElMessage } from 'element-plus'
import htmlToPdf from './pdf'
import { infoType } from '../components/surveyDraw/index.data.js'

// 导出
export const exportPdf = (dom: HTMLCanvasElement) => {
  const option = {
    width: 210,
    height: (dom.height / dom.width) * 210,
  }
  // 将canvas还原后导出
  htmlToPdf.exportPdf(dom, '标注', option)
}

// 打印
export const printPdf = (dom: HTMLCanvasElement) => {
  const option = {
    width: 210,
    height: (dom.height / dom.width) * 210,
  }
  // 将canvas还原后打印
  htmlToPdf.printPdf(dom, option)
}

// 计算直线距离
export const handleCalcTheLine = ({ startX, startY, endX, endY }: { startX: number, startY: number, endX: number, endY: number }) => {
  let x = Math.abs(startX - endX)
  let y = Math.abs(startY - endY)
  let long = Math.hypot(x, y)
  return long
}
// 坐标系转换
export const getCanvasPosition = (canvas: HTMLCanvasElement, scale: number, clientX: number, clientY: number) => {
  const rect = canvas.getBoundingClientRect()
  return {
    x: (clientX - rect.left - canvas.width / 2) / scale,
    y: (clientY - rect.top - canvas.height / 2) / scale,
  }
}

// 绘制线段
export const drawLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  switch (curLineInfo.lineType) {
    case 'solid':
      drawSloidLine(ctx, curLineInfo)
      break
    case 'dashed':
      drawDashedLine(ctx, curLineInfo)
      break
    case 'arrow':
      drawArrowLine(ctx, curLineInfo)
      break
    case 'doubleArrow':
      drawDoubleArrow(ctx, curLineInfo)
      break
    default:
      break
  }
}
// 重新绘制线段
export const reDrawLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  switch (curLineInfo.lineType) {
    case 'solid':
      reDrawSloidLine(ctx, curLineInfo)
      break
    case 'dashed':
      reDrawDashedLine(ctx, curLineInfo)
      break
    case 'arrow':
      reDrawArrowLine(ctx, curLineInfo)
      break
    case 'doubleArrow':
      reDrawDoubleArrow(ctx, curLineInfo)
      break
    default:
      break
  }
}
// 绘制实线
export const drawSloidLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  ctx.moveTo(curLineInfo.startX, curLineInfo.startY)
  ctx.lineTo(curLineInfo.endX, curLineInfo.endY)
  ctx.stroke()
}

// 重新绘制实线
export const reDrawSloidLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  // 绘制线段
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  ctx.moveTo(
    curLineInfo.startX + curLineInfo.translateX / curLineInfo.scale,
    curLineInfo.startY + curLineInfo.translateY / curLineInfo.scale
  )
  ctx.lineTo(
    curLineInfo.endX + curLineInfo.translateX / curLineInfo.scale,
    curLineInfo.endY + curLineInfo.translateY / curLineInfo.scale
  )
  ctx.stroke()
}
// 绘制虚线
export const drawDashedLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  ctx.setLineDash([10, 5])
  ctx.moveTo(curLineInfo.startX, curLineInfo.startY)
  ctx.lineTo(curLineInfo.endX, curLineInfo.endY)
  ctx.stroke()
}
// 重新绘制虚线
export const reDrawDashedLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  const changeX = curLineInfo.translateX / curLineInfo.scale
  const changeY = curLineInfo.translateY / curLineInfo.scale
  // 绘制线段
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.setLineDash([10, 5])
  ctx.lineWidth = curLineInfo.lineWidth
  ctx.moveTo(curLineInfo.startX + changeX, curLineInfo.startY + changeY)
  ctx.lineTo(curLineInfo.endX + changeX, curLineInfo.endY + changeY)
  ctx.stroke()
}
// 绘制单箭头
export const drawArrowLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  const { startX, startY, endX, endY } = curLineInfo
  let arrowX, arrowY
  const headLength = 10
  const theta = 30
  const angle = (Math.atan2(startY - endY, startX - endX) * 180) / Math.PI
  const angleLeft = ((angle + theta) * Math.PI) / 180
  const angleRight = ((angle - theta) * Math.PI) / 180
  // 左侧点计算
  const leftPointX = headLength * Math.cos(angleLeft)
  const leftPointY = headLength * Math.sin(angleLeft)

  // 右侧点计算
  const rightPointX = headLength * Math.cos(angleRight)
  const rightPointY = headLength * Math.sin(angleRight)
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  // 主线段
  ctx.moveTo(startX, startY)
  ctx.lineTo(endX, endY)
  // 上边箭头
  arrowX = endX + leftPointX
  arrowY = endY + leftPointY
  ctx.moveTo(arrowX, arrowY)
  ctx.lineTo(endX, endY)
  // 下边箭头
  arrowX = endX + rightPointX
  arrowY = endY + rightPointY
  ctx.moveTo(arrowX, arrowY)
  ctx.lineTo(endX, endY)
  ctx.stroke()
}
// 重新绘制单箭头
export const reDrawArrowLine = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  const { startX, startY, endX, endY } = curLineInfo
  const changeX = curLineInfo.translateX / curLineInfo.scale
  const changeY = curLineInfo.translateY / curLineInfo.scale
  let arrowX, arrowY
  const headLength = 10
  const theta = 30
  const angle = (Math.atan2(startY - endY, startX - endX) * 180) / Math.PI
  const angleLeft = ((angle + theta) * Math.PI) / 180
  const angleRight = ((angle - theta) * Math.PI) / 180
  // 左侧点计算
  const leftPointX = headLength * Math.cos(angleLeft)
  const leftPointY = headLength * Math.sin(angleLeft)

  // 右侧点计算
  const rightPointX = headLength * Math.cos(angleRight)
  const rightPointY = headLength * Math.sin(angleRight)
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  // 主线段
  ctx.moveTo(startX + changeX, startY + changeY)
  ctx.lineTo(endX + changeX, endY + changeY)
  // 上边箭头
  arrowX = endX + leftPointX
  arrowY = endY + leftPointY
  ctx.moveTo(arrowX + changeX, arrowY + changeY)
  ctx.lineTo(endX + changeX, endY + changeY)
  // 下边箭头
  arrowX = endX + rightPointX
  arrowY = endY + rightPointY
  ctx.moveTo(arrowX + changeX, arrowY + changeY)
  ctx.lineTo(endX + changeX, endY + changeY)
  ctx.stroke()
}
// 绘制双箭头
export const drawDoubleArrow = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  console.log('双箭头')
  const { startX, startY, endX, endY } = curLineInfo
  const changeX = curLineInfo.translateX / curLineInfo.scale
  const changeY = curLineInfo.translateY / curLineInfo.scale
  let arrowX, arrowY
  const headLength = 10
  const theta = 30
  const angle = (Math.atan2(startY - endY, startX - endX) * 180) / Math.PI
  const angleLeft = ((angle + theta) * Math.PI) / 180
  const angleRight = ((angle - theta) * Math.PI) / 180
  // 左侧点计算
  const leftPointX = headLength * Math.cos(angleLeft)
  const leftPointY = headLength * Math.sin(angleLeft)

  // 右侧点计算
  const rightPointX = headLength * Math.cos(angleRight)
  const rightPointY = headLength * Math.sin(angleRight)
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  // 主线段
  ctx.moveTo(startX, startY)
  ctx.lineTo(endX, endY)
  // 上边箭头
  arrowX = endX + leftPointX
  arrowY = endY + leftPointY
  ctx.moveTo(arrowX, arrowY)
  ctx.lineTo(endX, endY)
  // 下边箭头
  arrowX = endX + rightPointX
  arrowY = endY + rightPointY
  ctx.moveTo(arrowX, arrowY)
  ctx.lineTo(endX, endY)

  // Reverse length on the other side
  // 反向上边箭头
  arrowX = startX - leftPointX
  arrowY = startY - leftPointY
  ctx.moveTo(arrowX, arrowY)
  ctx.lineTo(startX, startY)
  // 反向下边箭头
  arrowX = startX - rightPointX
  arrowY = startY - rightPointY
  ctx.moveTo(arrowX, arrowY)
  ctx.lineTo(startX, startY)
  ctx.stroke()
}
// 重新绘制双箭头
export const reDrawDoubleArrow = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  console.log('双箭头')
  const { startX, startY, endX, endY } = curLineInfo
  const changeX = curLineInfo.translateX / curLineInfo.scale
  const changeY = curLineInfo.translateY / curLineInfo.scale
  let arrowX, arrowY
  const headLength = 10
  const theta = 30
  const angle = (Math.atan2(startY - endY, startX - endX) * 180) / Math.PI
  const angleLeft = ((angle + theta) * Math.PI) / 180
  const angleRight = ((angle - theta) * Math.PI) / 180
  // 左侧点计算
  const leftPointX = headLength * Math.cos(angleLeft)
  const leftPointY = headLength * Math.sin(angleLeft)

  // 右侧点计算
  const rightPointX = headLength * Math.cos(angleRight)
  const rightPointY = headLength * Math.sin(angleRight)
  ctx.beginPath()
  ctx.strokeStyle = curLineInfo.lineColor
  ctx.lineWidth = curLineInfo.lineWidth
  // 主线段
  ctx.moveTo(startX + changeX, startY + changeY)
  ctx.lineTo(endX + changeX, endY + changeY)
  // 上边箭头
  arrowX = endX + leftPointX
  arrowY = endY + leftPointY
  ctx.moveTo(arrowX + changeX, arrowY + changeY)
  ctx.lineTo(endX + changeX, endY + changeY)
  // 下边箭头
  arrowX = endX + rightPointX
  arrowY = endY + rightPointY
  ctx.moveTo(arrowX + changeX, arrowY + changeY)
  ctx.lineTo(endX + changeX, endY + changeY)

  // Reverse length on the other side
  // 反向上边箭头
  arrowX = startX - leftPointX
  arrowY = startY - leftPointY
  ctx.moveTo(arrowX + changeX, arrowY + changeY)
  ctx.lineTo(startX + changeX, startY + changeY)
  // 反向下边箭头
  arrowX = startX - rightPointX
  arrowY = startY - rightPointY
  ctx.moveTo(arrowX + changeX, arrowY + changeY)
  ctx.lineTo(startX + changeX, startY + changeY)
  ctx.stroke()
}
// 绘制文字
export const drawCharacters = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {

  // 线段与X轴的角度
  const theta = calcHorizontalAngle(curLineInfo)
  console.log(theta, 'theta')
  // 修改：计算线段中点和文字位置
  const midX = (curLineInfo.startX + curLineInfo.endX) / 2
  const midY = (curLineInfo.startY + curLineInfo.endY) / 2
  const lineText = ctx.measureText(curLineInfo.lineText)
  const textWidth = getTextWidth(theta, lineText.width)
  // 绘制
  ctx.save();
  ctx.font = `${curLineInfo.fontSize}px Arial`
  ctx.fillStyle = curLineInfo.fontColor
  ctx.textAlign = 'center'
  ctx.textBaseline = 'bottom'
  ctx.fillText(curLineInfo.lineText, midX + textWidth, midY - 5)
  ctx.restore();
}

// 重新绘制文字
export const reDrawCharacters = (ctx: CanvasRenderingContext2D, curLineInfo: infoType) => {
  const changeX = curLineInfo.translateX / curLineInfo.scale
  const changeY = curLineInfo.translateY / curLineInfo.scale
  const midX = (curLineInfo.startX + curLineInfo.endX) / 2 + changeX
  const midY = (curLineInfo.startY + curLineInfo.endY) / 2 + changeY
  // 线段与X轴的角度
  const theta = calcHorizontalAngle(curLineInfo)
  const lineText = ctx.measureText(curLineInfo.lineText)
  const textWidth = getTextWidth(theta, lineText.width)

  // 绘制
  ctx.save();
  ctx.font = `${curLineInfo.fontSize}px Arial`
  ctx.fillStyle = curLineInfo.fontColor
  ctx.textAlign = 'center'
  ctx.textBaseline = 'bottom'
  ctx.fillText(curLineInfo.lineText, midX + textWidth, midY - 5)
  ctx.restore();
}
// 计算两个坐标点之间与X轴的角度
export function calcHorizontalAngle(curLineInfo: infoType) {
  const dx = curLineInfo.endX - curLineInfo.startX;
  const dy = curLineInfo.endY - curLineInfo.startY;
  const radian = Math.atan2(dy, dx);  // 计算弧度
  return radian;
}

export const getTextWidth = (theta: number, lineWidth: number) => {
  // 根据象限调整文字移动位置
  if ((theta >= 0 && theta < 1.57) || theta <= -1.57) {
    return lineWidth * Math.abs(Math.sin(theta))
  } else {
    return -lineWidth * Math.abs(Math.sin(theta))
  }

}

// 获取线段长度
export const getLineText = (curLineInfo: infoType, unit: number) => {
  return curLineInfo.lineType !== 'arrow'
    ? `${(curLineInfo.long * unit).toFixed(2)}米`
    : ''
}

// 绘制指北针图例
export const drawCompassLegend = (
  ctx: CanvasRenderingContext2D,
  canvas: HTMLCanvasElement,
  img: any,
  translateX: number,
  translateY: number,
  scale: number,
  unit: number
) => {
  // 绘制图片（需确保image已加载）
  const getRealScale = getScale(canvas, unit)
  const rightImgX =
    (canvas.width / 2 - img.width - translateX - img.width / 2) / scale
  const rightImgY = (-canvas.height / 2 - translateY) / scale

  ctx.drawImage(
    img,
    rightImgX, // X坐标偏移量
    rightImgY, // Y坐标偏移量
    img.width / scale,
    img.height / scale
  )
  // 恢复原始坐标系
  // ctx.restore()
  if (unit) {
    const text = ctx.measureText(`比例：1 : ${getRealScale}`)
    const rightCompassWidth =
      (canvas.width / 2 - text.width - translateX - 20) / scale
    const rightCompassHeight =
      (-canvas.height / 2 + img.height - translateY + 20) / scale
    ctx.font = `${16 / scale}px Arial`
    ctx.fillStyle = 'white'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'bottom'
    ctx.fillText(
      `比例：1 : ${getRealScale}`,
      rightCompassWidth,
      rightCompassHeight
    )
  }
}

const getScale = (canvas: HTMLCanvasElement, unit: number) => {
  return Math.round((canvas.width * unit * 1000) / 210)
}

// canvas导出图片
export function exportSignature(canvas: HTMLCanvasElement) {
  return canvas.toDataURL('image/png', 1.0);  // 生成无损PNG格式
}